<?php
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>. 
//
// This file was modified by contributors of "BOINC Web Tweak" project.

class BoincAssignment {
	static function enum($where_clause) {
		$db = BoincDb::get();
		return $db->enum('assignment', 'BoincAssignment', $where_clause);
	}
}

define("NVALIDATE_STATES", 6);

// Converts a mysql-Timestamp to a user readable format
// @return String A user readable DateTime-String in UTC
// @param Integer $x The mysql-Timestamp to convert
function mysqltime_str($x) {
	if(strpos($x,"-")==4) {
		// Syntax of supplied mysql-timestamp is YYYY-MM-DD HH:MM:SS
		$year = substr($x,0,4);
		$month = substr($x,5,2);
		$day = substr($x,8,2);
		$hour = substr($x,11,2);
		$minute = substr($x,14,2);
		$second = substr($x,17,2);
	} else {
		// Syntax of supplied mysql-timestamp is YYYYMMDDHHMMSS
		$year = substr($x,0,4);
		$month = substr($x,4,2);
		$day = substr($x,6,2);
		$hour = substr($x,8,2);
		$minute = substr($x,10,2);
		$second = substr($x,12,2);
	
	}
	//make a Unix-Timestamp
	// echo "Time string is " . "$x";
	$time = mktime($hour,$minute,$second,$month,$day,$year);
	return time_str($time);
}

// Function prints a description of $table 
//
function print_describe_table_onecol($table, $which, $columns) {
	$result=mysql_query("SELECT * from $table LIMIT 1");
	$fields=mysql_num_fields($result);

	$avgnum=(int)($fields/$columns);
	if ($avgnum*$columns<$fields)
		$avgnum++;

	$actualcolumns=0;
	while ($avgnum*$actualcolumns<$fields)
		$actualcolumns++;

	if ($which>$actualcolumns)
		return 0;

	$bot=($which-1)*$avgnum;
	$top=$which*$avgnum;

	$width=100.0/$actualcolumns;

	//  echo "<td><table border='2' width=\"$width%\">\n";
	echo "<td><table class=\"bordered\" width=\"100%\">\n";
	echo "<tr><th class=\"left\">NAME</th><th class=\"left\">Type</th><th class=\"left\">Bytes</th>\n";
	for ($count=$bot; $count<$top; $count++) {
		if ($count<$fields) {
			$name= mysql_field_name($result, $count);
			$type= mysql_field_type($result, $count);
			$length=mysql_field_len($result, $count);
		} else {
			$name="<br /> ";
			$type="<br />";
			$length="<br />";
		}
		echo "\t<tr><td><strong>$name</strong></td><td>$type</td><td>$length</td></tr>\n";
	}
	echo "</table></td>";
	return 0;
}

function print_describe_table($table, $how_many_columns) {
	// Number of columns for showing table description
	echo "<h2>Description of <strong>$table</strong> table fields:</h2>\n";
	echo '<table width="100%">\n\t<tr>';

	for ($i=1; $i<=$how_many_columns; $i++)
		print_describe_table_onecol($table, $i, $how_many_columns);

	echo "\t</tr>\n</table>\n";
	return 0;
}

function print_detail_field() { ?>
	<tr>
		<td class="right">Detail level</td>
		<td>
			<select name="detail">
			<option value="low">low</option>
			<option value="high">high</option>
			</select>
		</td>
	</tr>
<?php }

function print_query_field() {
	$currenttime=time();
	$hourago=$currenttime-3600;
	$dayago=$currenttime-24*3600;
	$weekago=$currenttime-7*24*3600;
	echo "
		<tr>
			<td class=\"right\">Additional clauses</td>
			<td><input name=\"clauses\" size=\"100\"></td>
		</tr>
		<tr>
			<td class=\"right\">Unix times</td>
			<td>Now: <strong>$currenttime</strong> Hour ago: $hourago Day ago: $dayago Week ago: $weekago</td>
		</tr>
	";
}

function join_query_string($s1, $s2) {
	if ($s1) {
		if ($s2)
			return "$s1&s2";
		else
			return $s1;
	} else {
		return $s2;
	}
}

function append_sql_query($original,$addition,$first) {
	if ($first == 1)
		return $original . " where " . $addition;
	else
		return $original . " and " . $addition;
}

// SqlQueryString maps a bunch of form items to a SQL query
//
// The items are
// table			(name of table)
// id
// platformid
// appid
// workunitid
// hostid
// userid
// teamid
// nsecs			(modified_time > now - nsecs)
// received_time	(> x)
// server_state		(== x if z nonzero)
// outcome			(== x if z nonzero)
// client_state		(== x if z nonzero)
// exit_status		(== x if z nonzero)
// clauses			(literals added after the above)
// sort_by			(order by x desc added after all else)
//
// Once you've parsed the items (using parse_form_items()):
//
// get_select_query(n, m) returns the SQL query to get items from m to m+n
// get_url() returns the URL-encoded version of everything
// count() returns the number of records satisfying the query

class SqlQueryString {
	var $table;
	var $query;
	var $urlquery;

	function SqlQueryString() {
		if (isset($_GET['table']))
			$this->table = $_GET['table'];
		else
			$this->table = "";

		//$this->query = $_GET['query'];
		$this->query = "";
		$this->urlquery = "";
	}

	function add($clause) {
		//$clause=boinc_real_escape_string($clause);
		if (!$this->query)
			$this->query .= "where $clause";
		else
			$this->query .= " and $clause";
	}

	function addclause($clause) {
		if ($clause) {
			$c = urldecode($clause);
			$this->add("( $c )");
			$clause = urlencode($clause);
			$this->urlquery .= "&clauses=$clause";
		}
	}

	function addeq($name) {
		if (isset($_GET[$name]))
			$value = $_GET[$name];
		else
			$value = "";

		if (strlen($value)) {
			$this->add("$name = '$value'");
			$this->urlquery .= "&$name=".urlencode($value);
		}
	}

	function addeq_not_CHOOSE_ALL($name) {
		if (isset($_GET[$name]))
			$value = $_GET[$name];
		else
			$value = "";

		// On the selection menu, the ALL selection criteria sets (for example)
		// outcome=='CHOOSE_ALL' rather than a numeric value.  This means that
		// we enter no condition for this case.
		if (strlen($value) && strcmp("CHOOSE_ALL", $value)) {
			$this->add("$name = '$value'");
			$this->urlquery .= "&$name=".urlencode($value);
		}
	}

	function addgt($name) {
		if (isset($_GET[$name]))
			$value = $_GET[$name];
		else
			$value = '';

		if (strlen($value) && $value > 0) {
			$this->add("$name > '$value'");
			$this->urlquery .= "&$name=".urlencode($value);
		}
	}

	function addsort($name, $order) {
		if (isset($_GET[$name]))
			$value = $_GET[$name];
		else
			$value = null;

		if (isset($_GET[$order]))
			$order = $_GET[$order];
		else
			$order = null;

		if (strlen($value)) {
			if ($order == 'asc') {
				$this->query .= " order by $value asc";
				$this->urlquery .= "&sort_by_order=".urlencode($order);
			} else {
				$this->query .= " order by $value desc";
				$this->urlquery .= "&$name=".urlencode($value);
			}
		}
	}

	function count() {
		$count_query = "select count(*) as cnt from $this->table $this->query";
		$result = mysql_query($count_query);
		if (!$result) return 0;
		$res = mysql_fetch_object($result);
		mysql_free_result($result);
		return $res->cnt;
	}

	function get_select_query($entries_to_show, $start_at) {
		if ($entries_to_show) {
			if ($start_at)
				return "select * from $this->table $this->query limit $start_at,$entries_to_show";
			else
				return "select * from $this->table $this->query limit $entries_to_show";
		} else {
			return "select * from $this->table $this->query";
		}
	}

	function get_url($base = "db_action.php") {
		$s = $base . "?table=$this->table$this->urlquery";
		return $s;
	}

	function process_form_items() {
		$this->addeq('id');
		$this->addeq('platformid');
		$this->addeq('appid');
		$this->addeq('workunitid');
		$this->addeq('hostid');
		$this->addeq('userid');
		$this->addeq('teamid');
		$this->addeq('exit_status');

		if (isset($_GET['nsecs']))
			$_GET['mod_time'] = date("YmdHis",time() - $_GET['nsecs']);

		$this->addgt('mod_time');
		$this->addeq_not_CHOOSE_ALL('server_state');
		$this->addeq_not_CHOOSE_ALL('outcome');
		$this->addeq_not_CHOOSE_ALL('client_state');
		$this->addeq_not_CHOOSE_ALL('validate_state');
		$clauses = get_str("clauses", true);

		if (strstr($clauses, ";")) 
			error_page("bad clause");

		if ($clauses)
			$this->addclause($clauses);

		$this->addsort('sort_by', 'sort_by_order');
	}
}


function link_results($n, $mq, $query, $clauses) {
	if ($n == '0') { // intentional compare by string
		return "0";
	} else {
		if(strlen($clauses))
			return "<a href=\"db_action.php?table=result&amp;query=$mq&$query&amp;clauses=".urlencode($clauses)."&amp;sort_by=mod_time&amp;detail=low\">$n</a>";
		else
			return "<a href=\"db_action.php?table=result&amp;query=$mq&$query&amp;sort_by=mod_time&amp;detail=low\">$n</a>";
	}
}
// Decode ErrorNumber into human readable, taken from lib/error_numbers.h keep this up to date
// @return String A human readable error message
// @param Integer $x An error number
function result_error_mask_str($x){
	switch($x){
	case 0: return "";
	case -100: return "ERR_SELECT";
	case -102: return "ERR_READ";
	case -103: return "ERR_WRITE";
	case -104: return "ERR_FREAD";
	case -105: return "ERR_FWRITE";
	case -106: return "ERR_IO";
	case -107: return "ERR_CONNECT";
	case -108: return "ERR_FOPEN";
	case -109: return "ERR_RENAME";
	case -110: return "ERR_UNLINK";
	case -111: return "ERR_OPENDIR";
	case -112: return "ERR_XML_PARSE";
	case -113: return "ERR_GETHOSTBYNAME";
	case -114: return "ERR_GIVEUP_DOWNLOAD";
	case -115: return "ERR_GIVEUP_UPLOAD";
	case -116: return "ERR_NULL";
	case -117: return "ERR_NEG";
	case -118: return "ERR_BUFFER_OVERFLOW";
	case -119: return "ERR_MD5_FAILED";
	case -120: return "ERR_RSA_FAILED";
	case -121: return "ERR_OPEN";
	case -122: return "ERR_DUP2";
	case -123: return "ERR_NO_SIGNATURE";
	case -124: return "ERR_THREAD";
	case -125: return "ERR_SIGNAL_CATCH";
	case -126: return "ERR_QUIT_REQUEST";
	case -127: return "ERR_UPLOAD_TRANSIENT";
	case -128: return "ERR_UPLOAD_PERMANENT";
	case -129: return "ERR_IDLE_PERIOD";
	case -130: return "ERR_ALREADY_ATTACHED";
	case -131: return "ERR_FILE_TOO_BIG";
	case -132: return "ERR_GETRUSAGE";
	case -133: return "ERR_BENCHMARK_FAILED";
	case -134: return "ERR_BAD_HEX_FORMAT";
	case -135: return "ERR_USER_REJECTED";
	case -136: return "ERR_DB_NOT_FOUND";
	case -137: return "ERR_DB_NOT_UNIQUE";
	case -138: return "ERR_DB_CANT_CONNECT";
	case -139: return "ERR_GETS";
	case -140: return "ERR_SCANF";
	case -141: return "ERR_STRCHR";
	case -142: return "ERR_STRSTR";
	case -143: return "ERR_READDIR";
	case -144: return "ERR_SHMGET";
	case -145: return "ERR_SHMCTL";
	case -146: return "ERR_SHMAT";
	case -147: return "ERR_FORK";
	case -148: return "ERR_EXEC";
	case -149: return "ERR_NOT_EXITED";
	case -150: return "ERR_NOT_IMPLEMENTED";
	case -151: return "ERR_GETHOSTNAME";
	case -152: return "ERR_NETOPEN";
	case -153: return "ERR_SOCKET";
	case -154: return "ERR_FCNTL";
	case -155: return "ERR_AUTHENTICATOR";
	case -156: return "ERR_SCHED_SHMEM";
	case -157: return "ERR_ASYNCSELECT";
	case -158: return "ERR_BAD_RESULT_STATE";
	case -159: return "ERR_DB_CANT_INIT";
	case -160: return "ERR_NOT_UNIQUE";
	case -161: return "ERR_NOT_FOUND";
	case -162: return "ERR_NO_EXIT_STATUS";
	case -163: return "ERR_FILE_MISSING";
	case -164: return "ERR_NESTED_UNHANDLED_EXCEPTION_DETECTED";
	case -165: return "ERR_SEMGET";
	case -166: return "ERR_SEMCTL";
	case -167: return "ERR_SEMOP";
	case -168: return "ERR_FTOK";
	case -169: return "ERR_SOCKS_UNKNOWN_FAILURE";
	case -170: return "ERR_SOCKS_REQUEST_FAILED";
	case -171: return "ERR_SOCKS_BAD_USER_PASS";
	case -172: return "ERR_SOCKS_UNKNOWN_SERVER_VERSION";
	case -173: return "ERR_SOCKS_UNSUPPORTED";
	case -174: return "ERR_SOCKS_CANT_REACH_HOST";
	case -175: return "ERR_SOCKS_CONN_REFUSED";
	case -176: return "ERR_TIMER_INIT";
	case -177: return "ERR_RSC_LIMIT_EXCEEDED";
	case -178: return "ERR_INVALID_PARAM";
	case -179: return "ERR_SIGNAL_OP";
	case -180: return "ERR_BIND";
	case -181: return "ERR_LISTEN";
	case -182: return "ERR_TIMEOUT";
	case -183: return "ERR_PROJECT_DOWN";
	case -184: return "ERR_HTTP_ERROR";
	case -185: return "ERR_RESULT_START";
	case -186: return "ERR_RESULT_DOWNLOAD";
	case -187: return "ERR_RESULT_UPLOAD";
	case -189: return "ERR_INVALID_URL";
	case -190: return "ERR_MAJOR_VERSION";
	case -191: return "ERR_NO_OPTION";
	case -192: return "ERR_MKDIR";
	case -193: return "ERR_INVALID_EVENT";
	case -194: return "ERR_ALREADY_RUNNING";
	case -195: return "ERR_NO_APP_VERSION";  
	case -196: return "ERR_WU_USER_RULE";	
	case -197: return "ERR_ABORTED_VIA_GUI";
	case -198: return "ERR_INSUFFICIENT_RESOURCE";
	case -199: return "ERR_RETRY";
	case -200: return "ERR_WRONG_SIZE";
	case -201: return "ERR_USER_PERMISSION";
	case -202: return "ERR_SHMEM_NAME";
	case -203: return "ERR_NO_NETWORK_CONNECTION";
	case -204: return "ERR_IN_PROGRESS";
	case -205: return "ERR_BAD_EMAIL_ADDR";
	case -206: return "ERR_BAD_PASSWD";
	case -207: return "ERR_NONUNIQUE_EMAIL";
	case -208: return "ERR_ACCT_CREATION_DISABLED";
	case -209: return "ERR_ATTACH_FAIL_INIT";
	case -210: return "ERR_ATTACH_FAIL_DOWNLOAD";
	case -211: return "ERR_ATTACH_FAIL_PARSE";
	case -212: return "ERR_ATTACH_FAIL_BAD_KEY";
	case -213: return "ERR_ATTACH_FAIL_FILE_WRITE";
	case -214: return "ERR_ATTACH_FAIL_SERVER_ERROR";
	case -215: return "ERR_SIGNING_KEY";
	case -216: return "ERR_FFLUSH";
	case -217: return "ERR_FSYNC";
	case -218: return "ERR_TRUNCATE";
	case -219: return "ERR_WRONG_URL";
	case -220: return "ERR_DUP_NAME";
	case -221: return "ERR_ABORTED_BY_PROJECT";
	case -222: return "ERR_GETGRNAM";
	case -223: return "ERR_CHOWN";
	case -224: return "ERR_FILE_NOT_FOUND";
	case -225: return "ERR_BAD_FILENAME";
	case -226: return "ERR_TOO_MANY_EXITS";
	case -227: return "ERR_RMDIR";
	case -228: return "ERR_CHILD_FAILED";
	case -229: return "ERR_SYMLINK";
	case -230: return "ERR_DB_CONN_LOST";
	default: return "Unknown error number";
	}
}
// Determines if in stderr_out is an error reported and prints as human readable String
// @return String A human readable string if error otherwise FALSE
// @param String $stderr_out the stderr_out value to parse
function stderr_error_string($stderr_out){
	$y = parse_element($stderr_out, "<error_code>");
	$x = 0;
	if ($y)
		$x = (int)$y;

	if (0<=$x && $x<=9)
		return FALSE;
	else
		return "$x ".result_error_mask_str($x);
}
//
function exit_status_string($result) {
	$x = $result->exit_status;
	if ($x == 0) {
		$y = parse_element($result->stderr_out, "<exit_status>");
		if ($y)
			$x = (int)$y;
	}

	if (0<=$x && $x<=9)
		return "$x ".result_error_mask_str($x);
	else
		return sprintf("%d (0x%x)", $x, $x). " ".result_error_mask_str($x);
}

function show_result_summary() {

	$ntotal =0;	 // TODO: how to count $result?
	$nvalid = 0;	// for SUCCESS results
	$ninvalid = 0;
	$nfile_deleted = 0;

	$server_state = array();
	$outcome = array();
	$client_state = array();

	for ($ss=1; $ss<6; $ss++)
		$server_state[$ss] = 0;

	for ($ro=0; $ro<8; $ro++)
		$outcome[$ro] = 0;

	for ($cs=1; $cs<7; $cs++)
		$client_state[$cs] = 0;

	for ($fds=0; $fds<4; $fds++)
		$delete_state[$fds] = 0;

	for ($vs=0; $vs<NVALIDATE_STATES; $vs++)
		$validate_state[$vs]=0;

	$_GET['table'] = 'result';
	$_GET['sort_by'] = ''; // ignore sort

	if (isset($_GET['appid']))
		$query_appid = $_GET['appid'];
	else
		$query_appid = "";
 
	$query_mod_time = 0;
	if (isset($_GET['nsecs'])) {
		//$query_mod_time = time() - $_GET['nsecs'];
		$query_mod_time = $_GET['nsecs'];
	}

	if (isset($_GET['workunitid']))
		$query_wuid = $_GET['workunitid'];
	else
		$query_wuid = null;

	$q = new SqlQueryString();
	$q->process_form_items();

// Important: these need to be kept consistent with db/boinc_db.h and lib/result_state.h
	$main_query = "
SELECT COUNT(id) AS nTotal,
	   SUM(case when server_state = '1' then 1 else 0 end) AS serverstate_inactive,
	   SUM(case when server_state = '2' then 1 else 0 end) AS serverstate_unset,
	   SUM(case when server_state = '3' then 1 else 0 end) AS serverstate_unset_seq,
	   SUM(case when server_state = '4' then 1 else 0 end) AS serverstate_inprogress,
	   SUM(case when server_state = '5' then 1 else 0 end) AS serverstate_over,
	   SUM(case when server_state = '5' and outcome = '0' then 1 else 0 end) AS outcome_init,
	   SUM(case when server_state = '5' and outcome = '1' then 1 else 0 end) AS outcome_success,
	   SUM(case when server_state = '5' and outcome = '2' then 1 else 0 end) AS outcome_couldntsend,
	   SUM(case when server_state = '5' and outcome = '3' then 1 else 0 end) AS outcome_failure,
	   SUM(case when server_state = '5' and outcome = '4' then 1 else 0 end) AS outcome_noreply,
	   SUM(case when server_state = '5' and outcome = '5' then 1 else 0 end) AS outcome_didntneed,
	   SUM(case when server_state = '5' and outcome = '6' then 1 else 0 end) AS outcome_validateerror,
	   SUM(case when server_state = '5' and outcome = '7' then 1 else 0 end) AS outcome_clientdetached,
	   SUM(case when server_state = '5' and outcome = '1' and validate_state = '0' then 1 else 0 end) AS validate_init,
	   SUM(case when server_state = '5' and outcome = '1' and validate_state = '1' then 1 else 0 end) AS validate_valid,
	   SUM(case when server_state = '5' and outcome = '1' and validate_state = '2' then 1 else 0 end) AS validate_invalid,
	   SUM(case when server_state = '5' and outcome = '1' and validate_state = '3' then 1 else 0 end) AS validate_nocheck,
	   SUM(case when server_state = '5' and outcome = '1' and validate_state = '4' then 1 else 0 end) AS validate_inconclusive,
	   SUM(case when server_state = '5' and outcome = '1' and validate_state = '5' then 1 else 0 end) AS validate_too_late,
	   SUM(case when server_state = '5' and outcome = '1' and file_delete_state = '0' then 1 else 0 end) AS filedeletestate_init,
	   SUM(case when server_state = '5' and outcome = '1' and file_delete_state = '1' then 1 else 0 end) AS filedeletestate_ready,
	   SUM(case when server_state = '5' and outcome = '1' and file_delete_state = '2' then 1 else 0 end) AS filedeletestate_done,
	   SUM(case when server_state = '5' and outcome = '1' and file_delete_state = '3' then 1 else 0 end) AS filedeletestate_error,
	   SUM(case when server_state = '5' and outcome = '3' and client_state = '0' then 1 else 0 end) AS clientstate_init,
	   SUM(case when server_state = '5' and outcome = '3' and client_state = '1' then 1 else 0 end) AS clientstate_downloading,
	   SUM(case when server_state = '5' and outcome = '3' and client_state = '2' then 1 else 0 end) AS clientstate_downloaded,
	   SUM(case when server_state = '5' and outcome = '3' and client_state = '3' then 1 else 0 end) AS clientstate_computedone,
	   SUM(case when server_state = '5' and outcome = '3' and client_state = '4' then 1 else 0 end) AS clientstate_uploading,
	   SUM(case when server_state = '5' and outcome = '3' and client_state = '5' then 1 else 0 end) AS clientstate_uploaded,
	   SUM(case when server_state = '5' and outcome = '3' and client_state = '6' then 1 else 0 end) AS clientstate_aborted
FROM result WHERE 
	";

	if ($query_appid)
		$main_query .= "appid=$query_appid and ";

	if ($query_wuid)
		$main_query .= "workunitid=$query_wuid and ";

	if ($query_mod_time)
		$main_query .= "mod_time > DATE_SUB( NOW(), INTERVAL $query_mod_time SECOND )+0 and ";

	$main_query .= "1=1";

	$urlquery = $q->urlquery;
	$result = mysql_query($main_query);

	// echo "Main query was $main_query<br/>";

	if ($result) {

		$res = mysql_fetch_object($result);
		$ntotal = $res->nTotal;

		$server_state[1] = $res->serverstate_inactive;
		$server_state[2] = $res->serverstate_unset;
		$server_state[3] = $res->serverstate_unset_seq;
		$server_state[4] = $res->serverstate_inprogress;
		$server_state[5] = $res->serverstate_over;

		$outcome[0] = $res->outcome_init;
		$outcome[1]	= $res->outcome_success;
		$outcome[2]	= $res->outcome_couldntsend;
		$outcome[3] = $res->outcome_failure;
		$outcome[4]	= $res->outcome_noreply;
		$outcome[5]	= $res->outcome_didntneed;
		$outcome[6] = $res->outcome_validateerror;
		$outcome[7]	= $res->outcome_clientdetached;

		$client_state[1] = $res->clientstate_downloading;
		$client_state[2] = $res->clientstate_downloaded;
		$client_state[3] = $res->clientstate_computedone;
		$client_state[4] = $res->clientstate_uploading;
		$client_state[5] = $res->clientstate_uploaded;
		$client_state[6] = $res->clientstate_aborted;

		$validate_state[0] = $res->validate_init;
		$validate_state[1] = $res->validate_valid;
		$validate_state[2] = $res->validate_invalid;
		$validate_state[3] = $res->validate_nocheck;
		$validate_state[4] = $res->validate_inconclusive;
		$validate_state[5] = $res->validate_too_late;

		$file_delete[0] = $res->filedeletestate_init;
		$file_delete[1] = $res->filedeletestate_ready;
		$file_delete[2] = $res->filedeletestate_done;
		$file_delete[3] = $res->filedeletestate_error;

		$nfile_deleted = $res->filedeletestate_ready + $res->filedeletestate_done + $res->filedeletestate_error;
		mysql_free_result($result);
	}


	?><table>
	<tr>
		<td><h2><?php echo link_results("$ntotal results", $urlquery, '', '') ?></h2></td>
		<td><h2><?php echo link_results("'Over' results", $urlquery, "server_state=5", '') ?></h2></td>
		<td><h2><?php echo link_results("'Success' results", $urlquery, "outcome=1", '') ?></h2></td>
		<td><h2><?php echo link_results("'Client error' results", $urlquery, "outcome=3", '') ?></h2></td>
	</tr>
	<tr>
		<td><table class="bordered">
			<tr><th>Server state</th><th># results</th></tr>

			<?php for ($ss=1; $ss<6; $ss++)
				row2(server_state_string($ss), link_results("$server_state[$ss]",  $urlquery,"server_state=$ss", '')); ?>

		</table></td>
		<td><table class="bordered">
			<tr><th>Outcome</th><th># results</th></tr>

			<?php for ($ro=0; $ro<8; $ro++)
				c_row2($outcome[$ro]?outcome_color($ro):'', outcome_string($ro), link_results("$outcome[$ro]", $urlquery, "outcome=$ro", '')); ?>

		</table></td>
		<td><table class="bordered">
			<tr><th>Validate state</th><th># results</th></tr>
			
			<?php for ($vs=0; $vs<NVALIDATE_STATES; $vs++)
				c_row2($validate_state[$vs]?validate_color($vs):'', validate_state_str($vs), link_results("$validate_state[$vs]", $urlquery, "validate_state=$vs", "outcome=1")); ?>

		</table>
		<table class="bordered">
			<tr><th>File Delete state</th><th># results</th></tr>
  
			<?php for ($fds=0; $fds<4; $fds++) {
				row2(file_delete_state_str($fds), link_results("$file_delete[$fds]", $urlquery, "outcome=1", "file_delete_state=$fds"));

			row2("Total files deleted", link_results("$nfile_deleted", $urlquery, "outcome=1", "(file_delete_state=1 or file_delete_state=2 or file_delete_state=3)")); ?>
	
		</table></td>
		<td><table class="bordered">
			<tr><th>Client state</th><th># results</th></tr>

			<?php for ($cs=1; $cs<7; $cs++)
				row2(client_state_string($cs), link_results("$client_state[$cs]", $urlquery, "client_state=$cs", "outcome=3")); ?>

		</table></td>
	</table><?php
}

function server_state_select() { ?>
	<select name="server_state">
		<option value="CHOOSE_ALL" selected="selected"> Any </option>

		<?php for($i=1; $i<6; $i++)
			echo "<option value=\"$i\"> "."[$i]&nbsp;&nbsp;".'   '.server_state_string($i)."</option>\n"; ?>

	</select><?php
}

function outcome_select() { ?>
	<select name="outcome">
		<option value="CHOOSE_ALL" selected="selected"> Any </option>

		<?php for($i=0; $i<8; $i++)
			echo "<option value=\"$i\"> "."[$i]&nbsp;&nbsp;".'   '.outcome_string($i)."</option>\n"; ?>

	</select><?php
}

function validate_state_select() { ?>
	<select name="validate_state">
		<option value="CHOOSE_ALL" selected="selected"> Any </option>

		<?php for($i=0; $i<NVALIDATE_STATES; $i++)
			echo "<option value=\"$i\"> "."[$i]&nbsp;&nbsp;".'   '.validate_state_str($i)."</option>\n"; ?>

	</select><?php
}

function client_state_select() { ?>
	<select name="client_state">
		<option value="CHOOSE_ALL" selected="selected"> Any </option>

		<?php for($i=0; $i<7; $i++)
			echo "<option value=\"$i\"> "."[$i]&nbsp;&nbsp;".client_state_string($i)."</option>\n"; ?>

	</select><?php
}

function result_sort_select() { ?>
	<select name="sort_by">
		<option value="">None</option>
		<option value="id">ID</option>
		<option value="sent_time">Sent time</option>
		<option value="mod_time">Modification time</option>
		<option value="received_time">Received time</option>
		<option value="exit_status">Exit status</option>
		<option value="hostid">Host ID</option>
		<option value="userid">User ID</option>
		<option value="app_version_num">App Version Number</option>
		<option value="cpu_time">CPU time</option>
		<option value="workunitid">Work Unit ID</option>
	</select><?php
}

function sort_order_select() { ?>
	<select name="sort_by_order">
		<option value="asc">Ascending</option>
		<option value="desc" selected="selected">Descending</option>
	</select><?php
}

function table_title($table) {
	switch($table) {
	case "platform": return "Platforms";
	case "app": return "Applications";
	case "app_version": return "Application Versions";
	case "host": return "Hosts";
	case "workunit": return "Workunits";
	case "result": return "Results";
	case "team": return "Teams";
	case "user": return "Users";
	case "profile": return "Profiles";
	default: return "????";
	}
}

function show_platform($platform) {
	start_table();
	row("ID", $platform->id);
	row("Created", time_str($platform->create_time));
	row("Name", $platform->name);
	row("User friendly name", $platform->user_friendly_name);
	row("","<a href=\"db_action.php?table=app_version&amp;platformid=$platform->id\">App versions for this platform</a>");
	end_table();
}

function show_app($app) {
	start_table();
	row("ID", $app->id);
	row("Created", time_str($app->create_time));
	row("Name", $app->name);
	row("User-friendly name", $app->user_friendly_name);
	row("Deprecated", $app->deprecated);
	row("Homogeneous redundancy", $app->homogeneous_redundancy);
	row("","<a href=\"db_action.php?table=app_version&amp;appid=$app->id\">App Versions for this application</a>");
	row("","<a href=\"db_action.php?table=workunit&amp;appid=$app->id&amp;detail=low\">Workunits for this application</a>");
	end_table();
}

function show_app_version($app_version) {
	start_table();
	row("ID", $app_version->id);
	row("Created", time_str($app_version->create_time));
	row("Application", "<a href=\"db_action.php?table=app&amp;id=$app_version->appid\">" . app_name_by_id($app_version->appid) . "</a>");
	row("Version num", $app_version->version_num);
	row("Platform", "<a href=\"db_action.php?table=platform&amp;id=$app_version->platformid\">" . platform_name_by_id($app_version->platformid) . "</a>" );
	row("XML doc", "<pre>".htmlspecialchars($app_version->xml_doc)."</pre>");
	row("Min_core_version", $app_version->min_core_version);
	row("Max_core_version", $app_version->max_core_version);
	//row("Message", $app_version->message);
	row("Deprecated", $app_version->deprecated);
	end_table();
}

function app_version_short_header() { ?>
	<tr>
		<th>ID</th>
		<th>Application</th>
		<th>Version</th>
		<th>Platform</th>
	</tr><?php
}

function show_app_version_short($app_version) {
	$x = app_name_by_id($app_version->appid);
	$y = platform_name_by_id($app_version->platformid);
	echo "
		<tr>
		<td><a href=\"db_action.php?table=app_version&amp;id=$app_version->id\">$app_version->id</a></td>
		<td><a href=\"db_action.php?table=app&amp;id=$app_version->appid\">$x</a></td>
		<td>$app_version->version_num</td>
		<td><a href=\"db_action.php?table=platform&amp;id=$app_version->platformid\">$y</a></td>
		</tr>
	";
}

function host_short_header() { ?>
	<tr>
		<th>host ID</th>
		<th>IP address</th>
		<th>name</th>
		<th>RAC</th>
		<th>total credit</th>
		<th>CPU</th>
		<th>OS</th>
	</tr><?php
}

function show_host_short($host) {
	echo "
		<tr>
		<td><a href=\"db_action.php?table=host&amp;id=$host->id\">$host->id</a></td>
		<td>$host->last_ip_addr</td>
		<td>$host->domain_name</td>
	";
	printf("<td>%.2f</td>", $host->expavg_credit);
	printf("<td>%.1f</td>", $host->total_credit);
	echo "<td>$host->p_vendor $host->p_model</td>
		<td>$host->os_name $host->os_version</td>
		</tr>
	";
}

function show_host($host) {
	start_table();

	row("ID", $host->id);
	row("Created", time_str($host->create_time));
	row("User", "<a href=\"db_action.php?table=user&id=$host->userid\">".user_name_by_id($host->userid)."($host->userid)</a>");
	row("Venue", $host->venue);
	row("Total credit", $host->total_credit);
	row("Average credit", $host->expavg_credit);
	row("Average update time", time_str($host->expavg_time));
	row("IP address", "$host->last_ip_addr<br>(same the last $host->nsame_ip_addr times)");
	row("External IP address", "$host->external_ip_addr<br>");
	row("Domain name", $host->domain_name);
	$x = $host->timezone/3600;
	if ($x >= 0) $x="+$x";
	row("Local Standard Time", "UTC $x hours");
	row("Number of CPUs", $host->p_ncpus);
	row("CPU", "$host->p_vendor $host->p_model");
	row("FP ops/sec", $host->p_fpops);
	row("Int ops/sec", $host->p_iops);
	row("memory bandwidth", $host->p_membw);
	row("Operating System", "$host->os_name $host->os_version");
	$x = $host->m_nbytes/(1024*1024);
	$y = round($x, 2);
	row("Memory", "$y MB");
	$x = $host->m_cache/1024;
	$y = round($x, 2);
	row("Cache", "$y KB");
	$x = $host->m_swap/(1024*1024);
	$y = round($x, 2);
	row("Swap Space", "$y MB");
	$x = $host->d_total/(1024*1024*1024);
	$y = round($x, 2);
	row("Total Disk Space", "$y GB");
	$x = $host->d_free/(1024*1024*1024);
	$y = round($x, 2);
	row("Free Disk Space", "$y GB");
	row("Avg network bandwidth (upstream)", "$host->n_bwup bytes/sec");
	row("Avg network bandwidth (downstream)", "$host->n_bwdown bytes/sec");
	$x = $host->avg_turnaround/86400;
	row("Average turnaround", round($x, 2)." days");
	row("Number of RPCs", $host->rpc_seqno);
	row("Last RPC", time_str($host->rpc_time));
	row("% of time client on", 100*$host->on_frac." %");
	row("% of time host connected", 100*$host->connected_frac." %");
	row("% of time user active", 100*$host->active_frac." %");
	row("# of results today", $host->nresults_today);
	row("Results", "<a href=\"db_action.php?table=result&amp;detail=low&amp;hostid=$host->id&amp;sort_by=sent_time\">click here</a>");
	end_table();

}

function wu_error_mask_str($s) {
	$x = "";
	if ($s & 1) {
		$x = $x."Couldn't send result;<br />";
		$s -= 1;
	}
	if ($s & 2) {
		$x = $x."Too many errors (may have bug);<br />";
		$s -= 2;
	}
	if ($s & 4) {
		$x = $x."Too many results (may be nondeterministic)<br />";
		$s -= 4;
	}
	if ($s & 8) {
		$x = $x."Too many total results<br />";
		$s -= 8;
	}
	if ($s & 16) {
		$x = $x."WU cancelled<br />";
		$s -= 16;
	}
	if ($s) {
		$x = $x."Unrecognized Error: $s<br />";
	}
	if (strlen($x)) {
		$x="<span style=\"color:#f33\">".$x."</span>";
	} else {
		$x="<br />";
	}
	return $x;
}

function assimilate_state_str($s) {
	switch($s) {
	case 0: return "Initial";
	case 1: return "Ready to assimilate";
	case 2: return "Assimilated";
	}
	echo "<strong>THIS IS AN INTERNAL BUG #1 [$s] IN BOINC: PLEASE CONTACT BOINC DEVELOPERS</strong><br />";
	return "Unknown";
}

function file_delete_state_str($s) {
	switch($s) {
	case 0: return "Initial";
	case 1: return "Ready to delete";
	case 2: return "Deleted";
	case 3: return "Delete Error";
	}
	echo "<strong>THIS IS AN INTERNAL BUG #2 [$s] IN BOINC: PLEASE CONTACT BOINC DEVELOPERS</strong><br />";
	return "Unknown";
}

function show_workunit($wu) {
	$_GET = array('workunitid' => $wu->id);
	show_result_summary();

	start_table();
	row("Created", time_str($wu->create_time));
	row("Transition Time", time_str($wu->transition_time));
	row("Last time modified",mysqltime_str($wu->mod_time));
	row("Name", $wu->name);
	row("XML doc", "<pre>".htmlspecialchars($wu->xml_doc)."</pre>");
	row("Application", "<a href=\"db_action.php?table=app&amp;id=$wu->appid\">" . app_name_by_id($wu->appid) . " [".$wu->appid."]</a>");
	row("Batch", $wu->batch);
	row("Estimated FP Operations", $wu->rsc_fpops_est);
	row("Max FP Operations", $wu->rsc_fpops_bound);
	row("Max Memory Usage", $wu->rsc_memory_bound);
	row("Max Disk Usage", $wu->rsc_disk_bound);
	row("Need validate?", ($wu->need_validate?"yes [":"no [").$wu->need_validate."]");
	row("Canonical resultid",
			"<a href=\"db_action.php?table=result&amp;id=$wu->canonical_resultid\">".$wu->canonical_resultid."</a>");
	row("Canonical credit", $wu->canonical_credit);
	//row("Timeout check time", time_str($wu->timeout_check_time));
	row("Delay bound", "$wu->delay_bound" . " =  " . time_diff($wu->delay_bound) );
	row("Error mask", wu_error_mask_str($wu->error_mask));
	row("File delete state", file_delete_state_str($wu->file_delete_state)." [".$wu->file_delete_state."]");
	row("Assimilation state", assimilate_state_str($wu->assimilate_state)." [".$wu->assimilate_state."]");
	// row("","<a href=db_action.php?table=result&workunitid=$wu->id&detail=low>Show associated results</a>");
	row("min quorum", $wu->min_quorum);
	row("target results", $wu->target_nresults);
	row("max error results", $wu->max_error_results);
	row("max total results", $wu->max_total_results);
	row("max success results", $wu->max_success_results);
	row("result template file",$wu->result_template_file);
	row("hr_class", $wu->hr_class);
	row("opaque", $wu->opaque);
	row("Priority", $wu->priority);
	end_table();
	echo "<div class=\"center\">";
	echo "<a href=\"show_log.php?s=$wu->name\">GREP LOGS FOR THIS WORKUNIT</a>";
	echo "</div>";
	echo "<p>";
}

function workunit_short_header() { ?>
	<tr>
		<th>WU ID</th>
		<th>canonical result</th>
		<th>error_mask</th>
		<th>file delete</th>
		<th>assimilate</th>
	</tr><?php
}

function show_workunit_short($wu) {
	if ($wu->canonical_resultid)
		$cr = "<a href=\"db_action.php?table=result&amp;id=$wu->canonical_resultid\">$wu->canonical_resultid</a>";
	else
		$cr = "none";

	$wu_link = "<a href=\"db_action.php?table=workunit&amp;id=".$wu->id."&amp;detail=high\">".$wu->id."</a>";
	$cr = $cr. " <a href=\"db_action.php?table=result&amp;workunitid=$wu->id&amp;detail=low\">all</a>";
	$e = wu_error_mask_str($wu->error_mask);
	$f = file_delete_state_str($wu->file_delete_state);
	$a = assimilate_state_str($wu->assimilate_state);
	echo "
		<tr>
		<td>$wu_link</td>
		<td>$cr</td>
		<td>$e</td>
		<td>$f</td>
		<td>$a</td>
		</tr>
	";
}


function server_state_string($s) {
	switch($s) {
	case 1: return "Inactive";
	case 2: return "Unsent";
	case 3: return "Unsent (in work seq)";
	case 4: return "In Progress";
	case 5: return "Over";
	}
	echo "<strong>THIS IS AN INTERNAL BUG #3 [$s] IN BOINC: PLEASE CONTACT BOINC DEVELOPERS</strong><br />";
	return "Unknown";
}

function outcome_string($s) {
	switch($s) {
	case 0: return "Init";
	case 1: return "Success";
	case 2: return "Couldn't send";
	case 3: return "Client error";
	case 4: return "No reply";
	case 5: return "Didn't need";
	case 6: return "Validate error";
	case 7: return "Client detached";
	}
	echo "<strong>THIS IS AN INTERNAL BUG #4 [$s] IN BOINC: PLEASE CONTACT BOINC DEVELOPERS</strong><br />";
	return "Unknown";
}

function client_state_string($s) {
	switch($s) {
	case 0: return "New";
	case 1: return "Downloading";
	case 2: return "Downloaded";
	case 3: return "Compute error";
	case 4: return "Uploading";
	case 5: return "Uploaded";
	case 6: return "Aborted";
	}
	echo "<strong>THIS IS AN INTERNAL BUG #5 [$s] IN BOINC: PLEASE CONTACT BOINC DEVELOPERS</strong><br />";
	return "Unknown";
}

function validate_state_str($s) {
	switch($s) {
	case 0: return "Initial";
	case 1: return "Valid";
	case 2: return "Invalid";
	case 3: return "Skipped";
	case 4: return "Inconclusive";
	case 5: return "Too late";
	}
	echo "<strong>THIS IS AN INTERNAL BUG #6 [$s] IN BOINC: PLEASE CONTACT BOINC DEVELOPERS</strong><br />";
	return "Unknown";
}

function host_user_link($hostid)
{
	if (!$hostid) return '----';

	$h = "<a href=\"db_action.php?table=host&amp;id=$hostid\">$hostid</a>";
	$result = mysql_query("select userid from host where id='$hostid' limit 1");
	if (!$result) return $h;
	$host = mysql_fetch_object($result);
	mysql_free_result($result);
	if (!$host->userid) return $h;
	$result = mysql_query("select id, name from user where id='$host->userid' limit 1");
	if (!$result) return $h;
	$user = mysql_fetch_object($result);
	mysql_free_result($result);
	return "$h<br /><span class=\"smalltext\">(<a href=\"db_action.php?table=user&amp;id=$user->id\">$user->name</a>)</span>";
}

function validate_color($validate_state) {
	switch ($validate_state) {
	   case 1: return '3c3'; // valid, green
	   case 2: return 'ffa500'; // invalid result, orange
	}
	return '';
}

function outcome_color($outcome) {
	switch($outcome) {
		 case 0: return '90c'; // "Init", purple 
		 case 1: return '3c3'; // "Success", green
		 case 3: return 'f33'; // "Client error", red
		 case 4: return 'f69'; // "No reply", pink 
		 case 6: return 'ff3'; // "Validate error", yellow
	}
	return '';
}

function credit_str($c) {
	if ($c) {
		return sprintf("%.3f", $c);
	} else {
		return '---';
	}
}

function show_result($result) {
	$wu_name = wu_name_by_id($result->workunitid);

	start_table();

	row("Created", time_str($result->create_time));
	row("Sent", time_str($result->sent_time));
	row("Report deadline", time_str($result->report_deadline));
	row("Received", time_str($result->received_time));
	row("Last time modified",mysqltime_str($result->mod_time));
	row("Name", $result->name);
	row("Workunit", "<a href=\"db_action.php?table=workunit&amp;id=$result->workunitid\">" . wu_name_by_id($result->workunitid) . "</a> [$result->workunitid]" );
	row("Server state", server_state_string($result->server_state)." [$result->server_state]");
	row("Outcome", outcome_string($result->outcome)." [$result->outcome]");
	row("Client state", client_state_string($result->client_state)." [$result->client_state]");
	row("Exit status", exit_status_string($result));
	row("Host ID", "<a href=\"db_action.php?table=host&amp;id=$result->hostid\">" . host_name_by_id($result->hostid) . "</a> [$result->hostid]");
	row("User ID", "<a href=\"db_action.php?table=user&amp;id=$result->userid\">" . user_name_by_id($result->userid) . "</a> [$result->userid]");
	row("CPU time", $result->cpu_time);
	row("XML doc in", "<pre>".htmlspecialchars($result->xml_doc_in)."</pre>");
	row("XML doc out", "<pre>".htmlspecialchars($result->xml_doc_out)."</pre>");
	row("stderr out", "<pre>".htmlspecialchars($result->stderr_out)."</pre>");

	if($error=stderr_error_string($result->stderr_out))
		row("error in stderr out", $error);

	row("Batch", $result->batch);
	row("File delete state", file_delete_state_str($result->file_delete_state)." [$result->file_delete_state]");
	row("Validate state", validate_state_str($result->validate_state)." [$result->validate_state]");
	row("claimed credit", $result->claimed_credit);
	row("Granted credit", $result->granted_credit);
	row("Application", "<a href=\"db_action.php?table=app&amp;id=$result->appid\">".app_name_by_id($result->appid)."</a>");
	row("App version", "<a href=\"db_action.php?table=app_version&amp;appid=$result->appid&amp;clauses=version_num%3D$result->app_version_num\">".$result->app_version_num."</a>");
	row("Random",$result->random);
	row("Opaque",$result->opaque);
	row("Teamid",$result->teamid);
	row("Priority",$result->priority);
	end_table();
	echo "<div class=\"center\">";
	echo "<a href=\"show_log.php?s=$result->name\">GREP LOGS FOR THIS RESULT</a>";
	echo "</div>";
	echo "<p>";
}

function result_short_header() { ?>
	<tr>
		<th>result ID</th>
		<th>WU ID</th>
		<th>server<br />state</th>
		<th>outcome</th>
		<th>client<br />state</th>
		<th>validate<br />state</th>
		<th>delete<br />state</th>
		<th>exit<br />status</th>
		<th>host<br />(user)</th>
		<th>app<br />ver</th>
		<th>
			received<br />
			<i>or</i> <span style="color:#f33">dead</span>
			<span style="color:#3c3">line</span> <br />
			<i>or</i> <span style="color:#90c">created</span>
		</th>
		<th>CPU<br />hours</th>
		<th>claimed<br />credit</th>
		<th>granted<br />credit</th>
	</tr><?php
}

function show_result_short($result) {
	$ss = server_state_string($result->server_state)." [$result->server_state]";
	$oc = outcome_string($result->outcome)." [$result->outcome]";
	$vs = validate_state_str($result->validate_state)." [$result->validate_state]";
	$cs2 = client_state_string($result->client_state)." [$result->client_state]";
	if ($result->outcome == 3) {
		$cs = client_state_string($result->client_state);
		$oc = "$oc ($cs)";
	}

	if ($result->received_time) {
		$received = time_str($result->received_time);
	} else {
		// result has not been received yet, so show report deadline either
		// in green if in the future or in red if in the past.
		$timenow=time();
		if ($result->report_deadline==0)
			$received = "<span style=\"color:#90c\">". time_str($result->create_time) . "</span>"; // not sent -- show create time in purple
		else if ($result->report_deadline>=$timenow)
			$received = "<span style=\"color:#3c3\">". time_str($result->report_deadline) . "</span>"; // overdue -- show deadline in red
		else
			$received = "<span style=\"color:#f33\">". time_str($result->report_deadline) . "</span>"; // in progress and not overdue -- show deadline in green
	}
	$version = $result->app_version_num;
	$outcome_color = outcome_color($result->outcome);
	$validate_color = validate_color($result->validate_state);
	$host_user = host_user_link($result->hostid);
	$cpu_hours = sprintf("%.1f",$result->cpu_time / 3600);
	$claimed_credit = credit_str($result->claimed_credit);
	$granted_credit = credit_str($result->granted_credit);
	$delete_state = file_delete_state_str($result->file_delete_state);

	echo "
		<tr>
		<td><a href=\"db_action.php?table=result&amp;id=$result->id\">$result->id</a></td>
		<td><a href=\"db_action.php?table=workunit&amp;id=$result->workunitid\">$result->workunitid</a></td>
		<td>$ss</td>
		<td bgcolor=$outcome_color>$oc</td>
		<td>$cs2</td>
		<td bgcolor=$validate_color>$vs</td>
		<td>$delete_state</td>
		<td>", exit_status_string($result), "</td>
		<td>$host_user</td>
		<td>$version</td>
		<td>$received</td>
		<td>$cpu_hours</td>
		<td>$claimed_credit</td>
		<td>$granted_credit</td>
		</tr>
	";
}

function show_user($user) {
	start_table();
	row("ID", $user->id);
	row("Created", time_str($user->create_time));
	row("Name", $user->name);
	row("Authenticator", $user->authenticator);
	row("Email address", $user->email_addr);
	row("Country", $user->country);
	row("Postal code", $user->postal_code);
	row("Total credit", $user->total_credit);
	row("Average credit", $user->expavg_credit);
	row("Last average time", time_str($user->expavg_time));
	row("Default venue", $user->venue);
	row("Hosts", "<a href=\"db_action.php?table=host&amp;userid=$user->id&amp;detail=low\">click</a>");
	row("Cross project ID", $user->cross_project_id);
	row("Password Hash", $user->passwd_hash);
	row("Donated", $user->donated);
	end_table();
}

function show_user_summary($maxuser) {
	$top_country = array();
	$top_language = array();

	$stats_res = mysql_query("select max(id) as maxuser,
							  SUM(case when has_profile = '1' then 1 else 0 end) as profuser,
							  SUM(case when teamid != '0' then 1 else 0 end) as teamuser
							  from user");
	$stats = mysql_fetch_assoc($stats_res);

	if ($maxuser > $stats['maxuser'])
		$maxuser = $stats['maxuser'];

	$user_res = mysql_query("select * from user order by posts desc limit ".$maxuser);
	$profile_res = mysql_query("select * from profile order by posts desc limit ".$maxuser);

	for ($i=1;$i<=$maxuser;$i++) {
		$user = mysql_fetch_object($user_res);
		$top10poster[$i] = $user;
		$top_country[$user->country] += 1;
	}

	for ($i=1;$i<=$maxuser;$i++) {
		$profile = mysql_fetch_object($profile_res);	
		if ($profile->language != '')
			$top_language[$profile->language] += 1;
	}

	mysql_free_result($user_res);
	mysql_free_result($profile_res);
	mysql_free_result($stats_res);

	echo "<table>
		<tr>
			<td><h2>General</h2></td>
			<td><h2>top10 Poster</h2></td>
			<td><h2>top$maxuser Countries</h2></td>
			<td><h2>top$maxuser Languages</h2></td>
		</tr>";
	echo "<tr>";
	echo "<td><table class=\"bordered\">
		<tr><th>&nbsp;</th><th>&nbsp;</th></tr>";

	row2_plain("Users:", $stats['maxuser']);
	row2_plain("Profiles:", $stats['profuser']);
	row2_plain("Team members:", $stats['teamuser']);

	echo "</table></td>";
	echo "<td><table class=\"bordered\">\n";
	echo "<tr><th>User</th><th># posts</th></tr>\n";

	for ($p=1; $p<=10; $p++)
		row2_plain(user_links_ops($top10poster[$p]), $top10poster[$p]->posts);
	
	echo "</table></td>";
	echo "<td><table class=\"bordered\">\n";
	echo "<tr><th>Country</th><th># users</th></tr>\n";
	arsort($top_country);
	
	foreach ($top_country as $key => $value)
		row2_plain($key, $value);

	echo "</table></td>";
	echo "<td><table class=\"bordered\">\n";
	echo "<tr><th>Language</th><th># users</th></tr>\n";
	arsort($top_language);
	
	foreach ($top_language as $key => $value)
		row2_plain($key, $value);
		
	echo "</table></td>";
	echo "</tr></table></td></tr>";
}

function team_type_string($s) {
	switch ($s) {
	case 1: return "Unclassified";
	case 2: return "Company";
	case 3: return "Primary school";
	case 4: return "Secondary school";
	case 5: return "Junior college";
	case 6: return "University or department";
	case 7: return "Government agency";
	default: return "Unknown";
	}
}

function show_team($team) {
	start_table();
	row("ID", $team->id);
	row("Team Founder", "<a href=\"db_action.php?table=user&amp;id=$team->userid\">" . user_name_by_id($team->userid) . "</a>");
	row("Name", $team->name);
	row("Name (HTML Formatted)", "<pre>" . htmlspecialchars($team->name_html) . "</pre>" );
	row("Url", "<a href=\"http://$team->url\">" . $team->url . "</a>");
	row("Type", team_type_string($team->type));
	row("Description", $team->description);
	row("", "<a href=\"db_action.php?table=user&amp;teamid=$team->id\">List All Members</a>");
	end_table();
}

function team_name_by_id($teamid) {
	$result = mysql_query("select * from team where id = $teamid");
	$team = mysql_fetch_object($result);
	return $team->name;
}

function user_name_by_id($user_id) {
	$result = mysql_query("select * from user where id = $user_id");
	$user = mysql_fetch_object($result);
	return $user->name;
}

function app_name_by_id($appid) {
	$result = mysql_query("select * from app where id = $appid");
	$app = mysql_fetch_object($result);
	return $app->name;
}

function wu_name_by_id($workunitid) {
	$result = mysql_query("select * from workunit where id = $workunitid");
	$wu = mysql_fetch_object($result);
	return $wu->name;
}

function platform_name_by_id($platformid) {
	$result = mysql_query("select * from platform where id = $platformid");
	$plat = mysql_fetch_object($result);
	return $plat->name;
}

function host_name_by_id($hostid) {
	$result = mysql_query("select * from host where id = $hostid");
	$host = mysql_fetch_object($result);
	if (!strlen($host->domain_name) && !strlen($host->last_ip_addr))
		return "(blank)";
	else
		return $host->domain_name . " (" . $host->last_ip_addr . ")";
	}
}

$cvs_version_tracker[]="\$Id: db_ops.inc 15975 2008-09-07 07:40:56Z davea $";  //Generated automatically - do not edit
?>
